package www.sofn.com.shopping.cart;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import www.sofn.com.accounts.AccountsService;
import www.sofn.com.accounts.domain.vo.WeChartMemberInfoVO;
import www.sofn.com.exception.ValidateException;
import www.sofn.com.goods.GoodsDisplayService;
import www.sofn.com.goods.domain.vo.GoodsDisplayInfoVO;
import www.sofn.com.shopping.cart.domain.pojo.ShoppingCartPO;
import www.sofn.com.shopping.cart.domain.vo.AddShoppingCartVO;
import www.sofn.com.shopping.cart.domain.vo.ShoppingCartGoodsInfoVO;
import www.sofn.com.shopping.cart.domain.vo.ShoppingCartOrderInfoVO;
import www.sofn.com.utils.GoodsUtils;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Service
public class ShoppingCartService {

    @Resource
    private ShoppingCartMapper mapper;

    @Resource
    private GoodsDisplayService goodsDisplayService;

    @Resource
    private AccountsService accountsService;

    @Transactional
    public void addShoppingCart(AddShoppingCartVO vo) {
        //查询商品
        final GoodsDisplayInfoVO goodsDisplayInfoVO = goodsDisplayService.getGoodsDisplayInfoById(vo.getGoodsId());
        if (ObjectUtil.isNull(goodsDisplayInfoVO)) throw new ValidateException("没找到该商品信息");
        boolean flag = true;
        for (int i = 0; i < goodsDisplayInfoVO.getGoodsAttr().getAttrValue().size(); i++) {
            if (StrUtil.equals(goodsDisplayInfoVO.getGoodsAttr().getAttrValue().get(i).getId(), vo.getGoodsAttrId())) {
                flag = false;
                break;
            }
        }
        if (flag) throw new ValidateException("没知道该商品规格");
        final ShoppingCartPO oldShoppingCartPO = mapper.selectOne(new LambdaQueryWrapper<ShoppingCartPO>().eq(ShoppingCartPO::getGoodsId, vo.getGoodsId()));
        //购物车存在该规格 只需要修改数量否则新增到购物车
        if (ObjectUtil.isNull(oldShoppingCartPO)) {
            final WeChartMemberInfoVO personal = accountsService.getPersonal();
            final ShoppingCartPO shoppingCartPO = new ShoppingCartPO();
            shoppingCartPO.setMemberId(Long.valueOf(personal.getId())).setGoodsId(Long.valueOf(vo.getGoodsId()));
            final List<ShoppingCartPO.AttrInfo> specsInfos = ListUtil.list(false);
            ShoppingCartPO.AttrInfo attrInfo = new ShoppingCartPO.AttrInfo();
            attrInfo.setId(vo.getGoodsAttrId()).setNum(vo.getGoodsNum());
            specsInfos.add(attrInfo);
            shoppingCartPO.setAttrInfos(specsInfos);
            mapper.insert(shoppingCartPO);
        } else {
            boolean specsFlog = true;
            for (int i = 0; i < oldShoppingCartPO.getAttrInfos().size(); i++) {
                if (StrUtil.equals(oldShoppingCartPO.getAttrInfos().get(i).getId(), vo.getGoodsAttrId())) {
                    oldShoppingCartPO.getAttrInfos().get(i).setNum(oldShoppingCartPO.getAttrInfos().get(i).getNum() + vo.getGoodsNum());
                    specsFlog = false;
                    break;
                }
            }
            if (specsFlog) {
                ShoppingCartPO.AttrInfo attrInfo = new ShoppingCartPO.AttrInfo();
                attrInfo.setId(vo.getGoodsAttrId()).setNum(vo.getGoodsNum());
                oldShoppingCartPO.getAttrInfos().add(attrInfo);
            }
            mapper.updateById(oldShoppingCartPO);
        }
    }

    public List<ShoppingCartGoodsInfoVO> finalShoppingCartGoodsInfo() {
        List<ShoppingCartGoodsInfoVO> shoppingCartGoodsInfoVOS = new ArrayList<>();
        final WeChartMemberInfoVO personal = accountsService.getPersonal();
        final List<ShoppingCartPO> shoppingCartPOS = mapper.selectList(new LambdaQueryWrapper<ShoppingCartPO>().eq(ShoppingCartPO::getMemberId, personal.getId()));
        if (shoppingCartPOS == null || shoppingCartPOS.size() == 0) return shoppingCartGoodsInfoVOS;
        Set<Long> goodsIds = new HashSet<>();
        Map<String, Integer> attrInfo = new HashMap<>();
        Map<Long,ShoppingCartPO> shoppingCartPOMap=new HashMap<>();
        shoppingCartPOS.forEach((v) -> {
            goodsIds.add(v.getGoodsId());
            v.getAttrInfos().forEach((item) -> {
                attrInfo.put(item.getId(), item.getNum());
            });
            shoppingCartPOMap.put(v.getGoodsId(),v);
        });
        List<GoodsDisplayInfoVO> goodsInfos = goodsDisplayService.findGoodsInfo(goodsIds);
        if (goodsInfos == null || goodsInfos.size() == 0) return shoppingCartGoodsInfoVOS;
        final List<ShoppingCartGoodsInfoVO> shoppingCartGoodsInfoVOList  =new ArrayList<>();
        goodsInfos.stream().forEach((v)->{
            final ShoppingCartPO shoppingCartPO = shoppingCartPOMap.get(Long.valueOf(v.getId()));
            if(ObjectUtil.isNotNull(shoppingCartPO)) {
                ShoppingCartGoodsInfoVO shoppingCartGoodsInfoVO = new ShoppingCartGoodsInfoVO();
                shoppingCartGoodsInfoVO.setId(String.valueOf(shoppingCartPO.getId()));
                shoppingCartGoodsInfoVO.setGoodsName(v.getGoodsName());
                shoppingCartGoodsInfoVO.setGoodsId(v.getId());
                shoppingCartGoodsInfoVO.setDefaultGoodsImg(GoodsUtils.getGoodsDefaultImg(v.getGoodsCarousel()));
                shoppingCartGoodsInfoVO.setTotalMarketPrice(BigDecimal.ZERO.setScale(2, RoundingMode.FLOOR));
                shoppingCartGoodsInfoVO.setTotalMemberPrice(BigDecimal.ZERO.setScale(2, RoundingMode.FLOOR));
                shoppingCartGoodsInfoVO.setAttrInfos(new ArrayList<>());
                v.getGoodsAttr().getAttrValue().forEach(attrItem -> {
                    if (attrInfo.containsKey(attrItem.getId())) {
                        final ShoppingCartGoodsInfoVO.AttrInfo temp = BeanUtil.toBean(attrItem, ShoppingCartGoodsInfoVO.AttrInfo.class);
                        temp.setNum(attrInfo.get(attrItem.getId()));
                        //总会员价
                        shoppingCartGoodsInfoVO.setTotalMemberPrice(
                                shoppingCartGoodsInfoVO.getTotalMemberPrice().add( attrItem.getMemberPrice().multiply(new BigDecimal(temp.getNum())))
                        );
                        //总市场价
                        shoppingCartGoodsInfoVO.setTotalMarketPrice(
                                shoppingCartGoodsInfoVO.getTotalMarketPrice().add( attrItem.getMemberPrice().multiply(new BigDecimal(temp.getNum())))
                        );
                        shoppingCartGoodsInfoVO.getAttrInfos().add(temp);
                    }
                });
                shoppingCartGoodsInfoVOList.add(shoppingCartGoodsInfoVO);
            }
        });
        return shoppingCartGoodsInfoVOList;
    }

    public Long getShoppingCartGoodsNum() {
        final WeChartMemberInfoVO personal = accountsService.getPersonal();
        return mapper.selectCount(new LambdaQueryWrapper<ShoppingCartPO>().eq(ShoppingCartPO::getMemberId, personal.getId()));
    }

    public List<ShoppingCartOrderInfoVO> generateShoppingCartOrderInfo(@NotNull List<String> ids) {
        final WeChartMemberInfoVO personal = accountsService.getPersonal();
        final List<ShoppingCartPO> shoppingCartPOS = mapper.selectList(
                new LambdaQueryWrapper<ShoppingCartPO>()
                        .eq(ShoppingCartPO::getMemberId,personal.getId())
                        .in(ShoppingCartPO::getId, ids));
        if (shoppingCartPOS == null || shoppingCartPOS.size() == 0) return null;
        Set<Long> goodsIds = new HashSet<>();
        //key:属性id value:数量
        Map<String, Integer> attrInfoMap = new HashMap<>();
        //key:商品id value:购物车Id
        Map<Long,Long> shoppingCartAndGoodsId=new HashMap<>();
        shoppingCartPOS.forEach((v) -> {
            goodsIds.add(v.getGoodsId());
            v.getAttrInfos().forEach((item) -> {
                attrInfoMap.put(item.getId(), item.getNum());
            });
            shoppingCartAndGoodsId.put(v.getGoodsId(),v.getId());
        });
        List<GoodsDisplayInfoVO> goodsInfos = goodsDisplayService.findGoodsInfo(goodsIds);
        if (goodsInfos == null || goodsInfos.size() == 0) return null;
        List<ShoppingCartOrderInfoVO> shoppingCartOrderInfoVOS=new ArrayList<>();
        goodsInfos.forEach(v->{
            String defaultGoodsImg=GoodsUtils.getGoodsDefaultImg( v.getGoodsCarousel());
            v.getGoodsAttr().getAttrValue().forEach(attrItem->{
                if(attrInfoMap.containsKey(attrItem.getId())){

                    //确定订单数据
                    ShoppingCartOrderInfoVO shoppingCartOrderInfoVO=new ShoppingCartOrderInfoVO();
                    shoppingCartOrderInfoVO.setId(String.valueOf(shoppingCartAndGoodsId.get(   Long.valueOf(v.getId()) )))
                     .setDefaultImg(StrUtil.isBlank(attrItem.getImg())?defaultGoodsImg:attrItem.getImg())
                     .setNum(attrInfoMap.get( attrItem.getId()))
                     .setAttrId(attrItem.getId())
                     .setAttrName(attrItem.getValue())
                     .setMarketPrice(attrItem.getMarketPrice())
                     .setMemberPrice(attrItem.getMemberPrice())
                     .setGoodsId(v.getId())
                     .setGoodsName(v.getGoodsName());
                    shoppingCartOrderInfoVOS.add(shoppingCartOrderInfoVO);
                }
            });
        });
        return shoppingCartOrderInfoVOS;
    }

    public void delete(Set<? extends Serializable> ids){
        mapper.deleteBatchIds(ids);
    }
}
